package com.mxx.common.utils;

import com.mxx.common.core.Entry;
import com.mxx.common.core.Pairs;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @Author itzgyw
 * @Date 2020-03-19
 * @Time 20:48
 * @Description: RoundingMode.CEILING：取右边最近的整数
 * <p>
 * RoundingMode.DOWN：去掉小数部分取整，也就是正数取左边，负数取右边，相当于向原点靠近的方向取整
 * <p>
 * RoundingMode.FLOOR：取左边最近的正数
 * <p>
 * RoundingMode.HALF_DOWN:五舍六入，负数先取绝对值再五舍六入再负数
 * <p>
 * RoundingMode.HALF_UP:四舍五入，负数原理同上
 * <p>
 * RoundingMode.HALF_EVEN:这个比较绕，整数位若是奇数则四舍五入，若是偶数则五舍六入
 * <p>
 * scale 保留小数点数量
 */
public class MathUtil {
    public static BigDecimal divide(BigDecimal decimal, BigDecimal decimal2) {
        if (BigDecimal.ZERO.compareTo(decimal) == 0 || BigDecimal.ZERO.compareTo(decimal2) == 0) {
            return BigDecimal.ZERO;
        }
        return decimal.divide(decimal2, 3, RoundingMode.HALF_UP);
    }

    public static BigDecimal divide(BigDecimal decimal, Long long2) {
        return divide(decimal, BigDecimal.valueOf(long2));
    }

    public static BigDecimal divide(Long long1, Long long2) {
        return divide(BigDecimal.valueOf(long1), BigDecimal.valueOf(long2));
    }

    /**
     * 保留两位小数
     *
     * @param floatValue 目标值
     * @return
     */
    public static float twoDecimal(float floatValue) {
        return twoDecimal(floatValue, RoundingMode.HALF_UP);
    }

    /**
     * 保留两位小数
     *
     * @param floatValue   目标值
     * @param roundingMode 小数点保留策略
     * @return
     */

    public static float twoDecimal(float floatValue, RoundingMode roundingMode) {
        return new BigDecimal(floatValue).setScale(2, roundingMode).floatValue();
    }

    /**
     * 保留两位小数
     *
     * @param doubleValue 目标值
     * @return
     */
    public static double twoDecimal(double doubleValue) {
        return twoDecimal(doubleValue, RoundingMode.HALF_UP);
    }

    /**
     * 保留两位小数
     *
     * @param doubleValue  目标值
     * @param roundingMode 小数点保留策略
     * @return
     */
    public static double twoDecimal(double doubleValue, RoundingMode roundingMode) {
        return new BigDecimal(doubleValue).setScale(2, roundingMode).floatValue();
    }

    /**
     * 保留两位小数
     *
     * @param bigDecimal 目标值
     * @return
     */
    public static BigDecimal twoDecimal(BigDecimal bigDecimal) {
        return twoDecimal(bigDecimal, RoundingMode.HALF_UP);
    }

    /**
     * 保留两位小数
     *
     * @param bigDecimal   目标值
     * @param roundingMode 小数点保留策略
     * @return
     */

    public static BigDecimal twoDecimal(BigDecimal bigDecimal, RoundingMode roundingMode) {
        return bigDecimal.setScale(2, roundingMode);
    }

    /**
     * 获取偏移量，始终为正数
     *
     * @param n1
     * @param n2
     * @return
     */
    public static Entry<Integer, Integer> offset(Integer n1, Integer n2) {
        int compare = n1.compareTo(n2);
        int offset = compare > 0 ? n1 - n2 : n2 - n1;
        return new Entry<>(compare, offset);
    }

    /**
     * 获取偏移量，始终为正数
     *
     * @param n1
     * @param n2
     * @return
     */
    public static Entry<Integer, Long> offset(Long n1, Long n2) {
        int compare = n1.compareTo(n2);
        Long offset = compare > 0 ? n1 - n2 : n2 - n1;
        return new Entry<>(compare, offset);
    }

    /**
     * 获取偏移量，始终为正数
     *
     * @param n1
     * @param n2
     * @return
     */
    public static Entry<Integer, BigDecimal> offset(BigDecimal n1, BigDecimal n2) {
        int compare = n1.compareTo(n2);
        BigDecimal offset = compare > 0 ? n1.subtract(n2) : n2.subtract(n1);
        return new Entry<>(compare, offset);
    }
}
